/* ====================================================================
 * Copyright (C) 2012 - Deniz Sezen
 * ====================================================================
 * File: dx_hook.h
 * Purpose: Contains the CFunctionHook class which is used to detour
 *	functions in Deus Ex: HR.
 * ====================================================================
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#ifndef _DX_HOOK_H
#define _DX_HOOK_H

/************************************************************************/
/* Constants.                                                           */
/************************************************************************/
#define JMP_SIZE 5

/************************************************************************/
/* Hook types.                                                          */
/************************************************************************/
enum 
{
	DET_TYPE_JMP=0, // Inject a jump.
	DET_TYPE_RET	// Replace ebp.
};

/************************************************************************/
/* The function hook class. NOTE that you must call DoPatch yourself!	*/
/************************************************************************/
class CFunctionHook
{
	public:
		unsigned char*	m_pTarget;
		unsigned char*	m_pTrampoline;
		void*			m_pRedirect;
		unsigned int    m_nSavedBytes;
		int				m_iDetourType;

	public:
		CFunctionHook(unsigned char* pTarget, void* pRedirect, int type);
		~CFunctionHook( void );

	public:
		DWORD MakeMemWritable(void* target, unsigned int size, DWORD prot);

		bool DoPatch_JMP( void );
		bool DoPatch_RET( void );

		void UndoPatch( void );

		unsigned char* GetTrampoline( void );
};

/************************************************************************/
/* Special thanks to LanceVorgin for this code.							*/
/* This code is useful for grabbing pointers to member functions of a	*/
/* class.																*/
/************************************************************************/
__forceinline __declspec(naked) DWORD __stdcall AnythingToDWORD( ... ){
	__asm{
		mov eax, dword ptr [esp+0x04]
		ret
	}
}

#endif